package com.googlecode.roids.net;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.net.URLConnection;

import com.googlecode.roids.os.Task;

public final class HttpUtil {
	
	public static final int BUFFER_SIZE = 512;
	
	public interface DownloadListener {
		void onStart(int length);
		void onProgress(byte[] data, int amount);
	}
	
	public static class TaskDownloadListener
		implements DownloadListener {
		
		private Task<?, ?, Integer, ?> task;
		private float fileSize = 0;
		private float chunkSize = 0;
		private float downloaded = 0;
		private float progressInterval;
		
		public TaskDownloadListener(Task<?, ?, Integer, ?> task, int progressInterval) {
			this.task 				= task;
			this.progressInterval	= progressInterval;
		}

		public void onStart(int length) {
			this.fileSize = length;
		}

		public void onProgress(byte[] data, int amount) {
			chunkSize += amount;
			if (chunkSize > progressInterval) {
				downloaded += chunkSize;
				chunkSize = 0;
				int progress = (int)((downloaded / fileSize) * 100.0f);
				task.sendProgress(progress);
			}
		}
		
	}
	
	public static void download(URL url, DownloadListener listener) 
		throws IOException {
		download(url.openConnection(), listener);
	}
	
	public static void download(URLConnection con, DownloadListener listener) 
		throws IOException {
		
		// get an input stream
		InputStream ips = con.getInputStream();
		
		// notify the listener that we've started
		if (listener!=null) {
			listener.onStart(con.getContentLength());
		}
		
		// start reading
		byte[] buffer = new byte[BUFFER_SIZE];
		int amount = 0;
		while ((amount=ips.read(buffer))!=-1) {
			if (listener!=null) {
				listener.onProgress(buffer, amount);
			}
		}
		
		// we're done
		ips.close();
		
	}
	
	public static void download(URL url, OutputStream out, DownloadListener listener) 
		throws IOException {
		download(url.openConnection(), out, listener);
	}
	
	public static void download(URLConnection con, final OutputStream out, final DownloadListener listener) 
		throws IOException {
		download(con, new DownloadListener() {
			public void onStart(int length) {
				if (listener!=null) { listener.onStart(length); }
			}
			
			public void onProgress(byte[] data, int amount) {
				try {
					out.write(data, 0, amount);
				} catch(IOException ioe) {
					throw new RuntimeException(ioe);
				}
				if (listener!=null) { listener.onProgress(data, amount); }
			}
		});
	}
	
}
